package com.ruoyi.web.controller;

import com.alibaba.fastjson2.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.business.PayCallBack;
import com.ruoyi.business.PayNotifyRequest;
import com.ruoyi.business.service.PayService;
import com.ruoyi.common.common.ResultBody;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @title: PayController
 * @copyright: copyright (c) 2023
 * @author: jiangguanjun
 * @date: 2023/10/20 16:31
 * @firstReview:
 * @lastReview:
 * @desc:
 */
@Api(value = "PayController", tags = "支付相关接口")
@RestController
@Slf4j

@RequestMapping("/pay")
public class PayController {

    @Autowired
    private RestTemplate wxPayRestTemplate ;

    @Autowired
    private PrivateKey privateKey ;

    @Autowired
    private AutoUpdateCertificatesVerifier verifier;

    /**
     * 商户APIv3密钥
     */
    @Value("${weixinpay.api-v3-key}")
    private String apiV3key  ;

    @Autowired
    private PayService payService ;


    @CrossOrigin
    @PostMapping("/testPay")
    public ResultBody<JSONObject> getCheckImage() throws Exception {

        JSONObject jsonObject = new JSONObject( ) ;
        jsonObject.put("mchid","1638595957") ;
        String out_trade_no = System.currentTimeMillis()+"" ;
        log.info("out_trade_no:::::::::::{}",out_trade_no);
        jsonObject.put("out_trade_no",out_trade_no) ;
        jsonObject.put("appid","wx8431359f8fa41916") ;
        jsonObject.put("description","测试") ;
        jsonObject.put("notify_url","https://www.chengdao.xyz/seo/pay/notify") ;
        JSONObject amount = new JSONObject() ;
        amount.put("total",1) ;
        amount.put("currency","CNY") ;
        jsonObject.put("amount",amount) ;
        JSONObject payer = new JSONObject() ;
        payer.put("openid","oSSrb58nv-0ISVCuK1fRqrydFMXg") ;

        jsonObject.put("payer",payer) ;

        // ========================

        HttpHeaders httpHeaders = new HttpHeaders() ;
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        String req = jsonObject.toJSONString() ;
        HttpEntity httpEntity = new HttpEntity(req,httpHeaders) ;

        String res = wxPayRestTemplate.postForObject("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi",httpEntity,String.class) ;
        JSONObject resJson = JSONObject.parseObject(res) ;
        String prepayId = resJson.getString("prepay_id") ;
        // 组装前端参数
        long timestamp = System.currentTimeMillis();//时间戳
        String nonceStr = WXPayUtil.generateNonceStr();//随机字符串
        String pack ="prepay_id="+ prepayId;//订单详情扩展字符串
        String paySign = getSign("wx8431359f8fa41916", timestamp, nonceStr, pack);//签名
        log.info("paySignpaySignpaySign="+paySign);
        JSONObject data = new JSONObject();
        data.put("appid","wx8431359f8fa41916");//appid
        data.put("timeStamp",String.valueOf(timestamp));
        data.put("nonceStr",nonceStr);
        data.put("package",pack);
        data.put("signType","RSA");//签名方式
        data.put("paySign",paySign);

        log.info("res::::{}",res);

        return ResultBody.success(data) ;

    }

    public String getSign(String appId, long timestamp, String nonceStr, String pack) throws Exception{
        String message = buildMessage(appId, timestamp, nonceStr, pack);
        String paySign= sign(message.getBytes("utf-8"));
        return paySign;
    }

    private String buildMessage(String appId, long timestamp, String nonceStr, String pack) {
        return appId + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + pack + "\n";
    }
    private String sign(byte[] message) throws Exception{
        Signature sign = Signature.getInstance("SHA256withRSA");
        //这里需要一个PrivateKey类型的参数，就是商户的私钥。
        //获取商户私钥
        sign.initSign(privateKey);
        sign.update(message);
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    @CrossOrigin
    @PostMapping("/notify")
    public JSONObject notify(@RequestBody JSONObject jsonObject) throws Exception {

        log.info("jsonObject::::::{}",jsonObject);

        /*for (Map.Entry<String, String> entry : jsonObject.entrySet()) {
            log.info("key::{},value:::{}",entry.getKey(), entry.getValue());
        }*/

       /* String sign = (String) jsonObject.get("sign");
        if(StringUtils.isBlank(sign)){
            return null ;
        }
        // 校验sign
        String calculatedSign = WXPayUtil.generateSignature(jsonObject, "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4CrFzK7xpnTNNbDJkQtTDVJFRZtMMGCw1Qw3hld27H+p4PXpvSUGrerpWmv/GMzIFibC18SfBilJ+YM5ZU/zS4c92sPCOqLacnkZzBhREs6L51GVnMsAHef4WlT+EBBKPZYHuxy2Gb8QslDiOTVCPSjALIDqdAHejksNqCnpeYSHz8FaeaZMvto0c7pOBtXSuw8P/45xai5e6GNiyCoVBaSGTGadOKq3+P6a6qVb2hNq67aAlko+NaijRtPytIfvpB50m4NHSSOt1LzFaUqR/ZllsGQlyD6gpNkZoPw2KytvSwEJ3WngTTPhTX2VSKgchdaEkIaxVA6emp7npYPI9AgMBAAECggEBAIfgFSyjkKIk1liF1hphoPVpPTRtBsm6GwFjtR7kZ2Sc5p3JPdhlrF8u593C561r5LVj95wMJD7moYr+a7pVoKYM4v+NGL0qYE/3JqoLRfGG8n8iSY9MT6v1bBs+KzuLSiymU6x3TuwfHiWPdMXS3PQ9YIUGUV/SlYGlfDKQ89EzAkEOM56m7gog+FgxLCOvX4lDQm5pg03cdYVARggUAik1RJ2AMC1kSefpDLbEG0Xj5kCcj4EH3ZpbRNXYux7Qel/aAFNt7N1nKXYLp9jCsBlunB/Bqlie2PeeXiGkWB1YF/6dFX/Egh03zme9+y54kH5kbEWpuoq0Jh/YdtJ0Pd0CgYEA5VRy+XnQM7AtP+krI+9hB9s7WHL9x4HHMWXSg2r58jLnA0RkFEolT7H4UQ/wqpdtKiBT9xIOvTrOU9thewqD9nW7ml2X5EZm7qTTsvPtOEb04lmG7pRruuXk1Q0sywQ/CVjhsLG+K+NORrPbZnCcjZI5TP046lgoj4r1jGKdbOsCgYEAzXHwHqs5Gf3K/acY0DHXoKhoaseXCR5q9IH3zzcLL+IKk6qB4kk/9/9YDkyIpyeXEp1z+QjPOrdXv2P/iOWQqoOV6cYf+DNW6A/Y98lsTThx2+eNMyI0O55gwuITnD60jhOvmKPprBuKbFCUJNMxygIAPIsmiH6bKkmpAq5hs3cCgYBu/S4f+4p+WZesxMZyP9pwGPRh3FVihzbGe4ckv1N0mpofhKwC/deM+I87fEF37o2Qw9CfVQf5IUrWXuiQyggP8e73yLBIdKJAgVlL1K5MfFrsaXPaZ86zx6u2SQgSwV1YwsGH6J4nU32Azm8y5vF9uvUsg6lWEZCf2Br69IdIPQKBgQC3S2tngW49sUA1VKr/vShbr0UR16b6PMhCA977Ymm5u9uh6aNeJ+pJseh3QXM+Z0UTF6WLz39MLJ2+JVKsadzLNQFAhEKrp+pmuxTh5jSZJL3467r/nwmpE2HTHe9PHGbsx8WH0t49bojuoGm7/S1TxLs/SQsFBqgbb4K54KlMewKBgQDaxmH3RjJEkG2OGEvNRUPAOJpbdxJS4+jqhlLkuJStMM1Q0tXLE4ziAPbfwLhLZpMA0McXMjAuGIQGCCsAQIBBNBkPn4bgJZh9RkEaR3s4ci/2Qu5Xz4nV1d1FqKIfY1oFQeYe90vnOag1RfLdDHJWbgb0r5wG80pdAHoep80Crw==", WXPayConstants.SignType.HMACSHA256);
        if(!sign.equals(calculatedSign)){
            return null ;
        }
        return null ;*/

        return null ;

    }




    @PostMapping("/callBack")
    public Map<String, String> xcxPayCallBack(HttpServletRequest request) {
        String signature = request.getHeader("Wechatpay-Signature");
        String serial = request.getHeader("Wechatpay-Serial");
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String body = "";
        try {
            StringBuilder sb = new StringBuilder();
            BufferedReader br = request.getReader();
            String str;
            while((str = br.readLine()) != null){
                sb.append(str);
            }
            body = sb.toString();
        } catch (Exception e) {
            log.info("小程序支付回调读取 body 异常", e);
        }
        log.info("小程序支付回调, Wechatpay-Signature:{}, Wechatpay-Serial:{}, Wechatpay-Timestamp:{}, Wechatpay-Nonce:{}, body:{}",
                signature, serial, timestamp, nonce, body);
        Map<String, String> result = new HashMap<>(2);
        try {

            // 1 签名验证，验证是否为微信服务器发送的报文(使用微信平台公钥对签名串和签名进行验签)
            String text = timestamp + "\n" + nonce + "\n" + body + "\n";
            if (!verifier.verify(serial, text.getBytes("utf-8"), signature))  {
                log.info("小程序支付回调验签失败，text：{}，signature：{}，serial：{}", text, signature, serial);
                result.put("code","FAIL");
                result.put("message","验签失败");
                return result;
            }

            // 2 解密
            PayCallBack payCallBack = JSONObject.parseObject(body, PayCallBack.class);
            if (payCallBack != null && payCallBack.getResource() != null) {
                PayCallBack.Resource resource = payCallBack.getResource();
                String decrypt = new AesUtil(apiV3key.getBytes("utf-8")).decryptToString(resource.getAssociated_data().getBytes(),
                        resource.getNonce().getBytes(), resource.getCiphertext());
                log.info("小程序支付回调，解密后信息：{}", decrypt);
                PayNotifyRequest notifyRequest = JSONObject.parseObject(decrypt, PayNotifyRequest.class);
                // 2.1 保存通知内容(非必须)

                // 3 根据解密后的信息更新订单状态
                // updateOrderStatus();
            }
            result.put("code","SUCCESS");
            result.put("message","成功");
        } catch (Exception e) {
            log.info("小程序支付回调异常", e);
            result.put("code","FAIL");
            result.put("message","失败");
        }
        // 4 响应
        log.info("小程序支付回调，响应结果：{}", result);
        return result;
    }


   /* @CrossOrigin
    @GetMapping("/testQueryByOut")
    public ResultBody<PayNotifyRequest> testQueryByOut(@RequestParam String outTradeNo) throws Exception {

        PayNotifyRequest payNotifyRequest =  payService.queryByOut(outTradeNo) ;
        return ResultBody.success(payNotifyRequest) ;

    }

    @CrossOrigin
    @PostMapping("/testRefundByOut")
    public ResultBody<RefundResult> testRefundByOut(@RequestBody RefundBO refundBO) throws Exception {

        RefundResult refundResult =  payService.refundByOut(refundBO) ;

        return ResultBody.success(refundResult) ;
    }*/
}
